package cn.framelife.rainbow.ui.wizard;


import java.sql.Connection;
import java.util.Properties;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.w3c.dom.Element;

import cn.framelife.rainbow.db.entity.ConnectionProperty;
import cn.framelife.rainbow.ui.entity.WizardMessage;
import cn.framelife.rainbow.ui.provider.ConnectionPageProvider;
import cn.framelife.rainbow.ui.view.ErrorMessageBox;
import cn.framelife.rainbow.util.DatabaseCache;
import cn.framelife.rainbow.util.JDBCUtil;
import cn.framelife.rainbow.util.StringUtil;
import cn.framelife.rainbow.util.xml.ConnectionXMLUtil;

/**
 * 数据库连接向导第一页
 * @author 潘广伟 p_3er@qq.com
 * @date 2013年11月4日 下午4:28:11 
 *
 */
public class ConnectionPage extends WizardPage {
	
	private Combo connectionNameCombo;
	private Text connectionURLField;
	private Text userNameField;
	private Text passwordField;
	private Combo driverTemplateCombo;
	private Combo driverClassNameCombo;
	private Text jarField;
	private Button addJarsButton;
	private Button savePasswordCheckButton;
	private Button testDriverButton;
	
	private Properties databaseTemplates;
	private Properties driverNames;
	private Element selectedConneciton;
	private ConnectionProperty connectionProperty;
	private ConnectionPageProvider provider;
	
	
	private boolean isShow = false;

	/**
	 * Create the wizard.
	 */
	public ConnectionPage(WizardMessage message) {
		super(message.getPageTitle());
		
		setTitle(message.getPageTitle());
		setDescription(message.getPageDescription());
		
		connectionProperty = new ConnectionProperty();
		provider = new ConnectionPageProvider();
	}

	/**
	 * Create contents of the wizard.
	 * @param parent
	 */
	public void createControl(Composite parent){
		Composite container = new Composite(parent, SWT.NULL);
		try {
			setControl(container);
			initUI(container);
			databaseTemplates = provider.loadDatabaseTemplates();
			driverNames = provider.loadDriverNames();
			
			driverTemplateCombo.setItems(provider.getDriverTemplateItems(databaseTemplates));
			driverClassNameCombo.select(1);
			
			connectionNameCombo.setItems(provider.getConnectionNames());
			events();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}
	
	
	@Override
	public IWizardPage getNextPage() {
		if(isShow && isConnection()){
			try {
				writeConnectionProperty();
				ModulePage nextPage = (ModulePage) super.getNextPage();
				nextPage.reflesh();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			return super.getNextPage();
		}
		
		isShow = true;
		return this;
	}

	/**
	 * 控件的事件
	 */
	private void events() {
		driverTemplateCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				connectionURLField.setText(databaseTemplates.getProperty (driverTemplateCombo.getText()));
			}
		});
		connectionNameCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					loadEditValues(connectionNameCombo.getText());
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		
		addJarsButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				IPath path = browse(null);
				if(path == null){
					return;
				}
				
				jarField.setText(path.toString());
				driverClassNameCombo.add(driverNames.getProperty(driverTemplateCombo.getText()));
				driverClassNameCombo.select(driverClassNameCombo.getItemCount()-1);
				
				testDriverButton.setEnabled(isTestConnection());
			}
		});
		
		testDriverButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if(isConnection()){
					ErrorMessageBox.showBox(getShell(), "Connection succese.");
				}
			}
		});
	}
	
	
	/**
	 * 是否可以点击TestConnection按钮
	 *
	 * @Title: isTestConnection 
	 * @param @return  
	 * @return boolean  
	 * @throws
	 */
	private boolean isTestConnection(){
		if(connectionNameCombo.getText().trim().length() > 0 && jarField.getText().trim().length() > 0){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 加载相关信息
	 * 
	 * @Title: setEditValues 
	 * @param   
	 * @return void     
	 * @throws Exception
	 */
	private void loadEditValues(String connectionName) throws Exception{
		if (StringUtil.isNotEmpty(connectionName)) {
			selectedConneciton = ConnectionXMLUtil.getSelectionConnection(connectionName);
			
			driverTemplateCombo.setText(ConnectionXMLUtil.getValue(selectedConneciton, "driverTemplate"));
			connectionNameCombo.setText(ConnectionXMLUtil.getValue(selectedConneciton, "name"));
			connectionURLField.setText(ConnectionXMLUtil.getValue(selectedConneciton, "connectionURL"));
			userNameField.setText(ConnectionXMLUtil.getValue(selectedConneciton, "username"));
			passwordField.setText(ConnectionXMLUtil.getValue(selectedConneciton, "password"));
			if(StringUtil.isNotEmpty(passwordField.getText().trim())){
				savePasswordCheckButton.setSelection(true);
			}
			driverClassNameCombo.setText(ConnectionXMLUtil.getValue(selectedConneciton, "driverClass"));
			jarField.setText(ConnectionXMLUtil.getValue(selectedConneciton, "jarURL"));
			testDriverButton.setEnabled(isTestConnection());
		}
	}
	
	/**
	 * 判断数据库是否连接成功
	 * @Title: isConnection 
	 * @param @return  
	 * @return boolean     
	 * @throws
	 */
	private boolean isConnection(){
		try {	
			setConnectionProperty();
			Connection connection = JDBCUtil.getConnection(this.connectionProperty);
			DatabaseCache.setConnection(connection);
			if (connection == null) {
				return false;
			}
		} catch (Exception e) {	
			ErrorMessageBox.showBox(getShell(), "Error while performing database connection:\r\n"+e.toString());
			return false;
		}
		return true;
	}
	
	
	/**
	 * 获取文件地址
	 * 
	 * @Title: browse 
	 * @param @param srcPath
	 * @param @param mustExxist
	 * @param @return  
	 * @return IPath     
	 * @throws
	 */
	private IPath browse(IPath srcPath){
		FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
		
		if(srcPath != null){
			if(srcPath.segmentCount() > 1){
				dialog.setFilterPath(srcPath.removeLastSegments(1).toOSString());
			}
			if(srcPath.segmentCount() > 0){
				dialog.setFileName(srcPath.lastSegment());
			}
		}
		
		String result = dialog.open();
		if(result == null){
			return null;
		}
		
		return new Path(result);
	}
	
	

	
	
	public void writeConnectionProperty() throws Exception{
		if(!savePasswordCheckButton.getSelection()){
			connectionProperty.setPassword("");
		}
		ConnectionXMLUtil.saveOrUpdate(connectionProperty);
	}

	private void setConnectionProperty() {
		connectionProperty.setConnectionName(connectionNameCombo.getText().trim());
		connectionProperty.setDriverTemplate(driverTemplateCombo.getText().trim());
		connectionProperty.setJarURL(jarField.getText().trim());
		connectionProperty.setDriverClass(driverClassNameCombo.getText().trim());
		connectionProperty.setConnectionURL(connectionURLField.getText().trim());
		connectionProperty.setUsername(userNameField.getText().trim());
		connectionProperty.setPassword(passwordField.getText().trim());
		DatabaseCache.setConnectionProperty(connectionProperty);
	}
	
	

	/**
	 * 初始化UI,由工具生成(没有重构)
	 * @param container
	 */
	private void initUI(Composite container) {
		container.setLayout(new GridLayout(3, false));
		new Label(container, SWT.NONE);
		
		Label connectionNameLabel = new Label(container, SWT.NONE);
		connectionNameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		connectionNameLabel.setText("Connection Name:");
		
		connectionNameCombo = new Combo(container, SWT.BORDER);
		GridData gd_driverNameField = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_driverNameField.widthHint = 415;
		connectionNameCombo.setLayoutData(gd_driverNameField);
		new Label(container, SWT.NONE);
		
		
		Label driverTemplateLabel = new Label(container, SWT.NONE);
		driverTemplateLabel.setText("Drivate Template:");
		
		driverTemplateCombo = new Combo(container, SWT.NONE);
		
		GridData gd_driverTemplateCombo = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_driverTemplateCombo.widthHint = 415;
		driverTemplateCombo.setLayoutData(gd_driverTemplateCombo);
		new Label(container, SWT.NONE);
		
		Label connectionURLLabel = new Label(container, SWT.NONE);
		connectionURLLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		connectionURLLabel.setText("Connection URL:");
		
		connectionURLField = new Text(container, SWT.BORDER);
		GridData gd_connectionURLField = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_connectionURLField.widthHint = 430;
		connectionURLField.setLayoutData(gd_connectionURLField);
		new Label(container, SWT.NONE);
		
		Label userNameLabel = new Label(container, SWT.NONE);
		userNameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		userNameLabel.setText("User Name:");
		
		userNameField = new Text(container, SWT.BORDER);
		GridData gd_userNameField = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_userNameField.widthHint = 430;
		userNameField.setLayoutData(gd_userNameField);
		new Label(container, SWT.NONE);
		
		Label passwordLabel = new Label(container, SWT.NONE);
		passwordLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		passwordLabel.setText("Password:");
		
		passwordField = new Text(container, SWT.BORDER | SWT.PASSWORD);
		passwordField.setEchoChar('*');
		GridData gd_passwordField = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_passwordField.widthHint = 430;
		passwordField.setLayoutData(gd_passwordField);
		
		Label firstSeparator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData gd_firstSeparator = new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1);
		gd_firstSeparator.widthHint = 600;
		firstSeparator.setLayoutData(gd_firstSeparator);
		
		Composite jarsComposite = new Composite(container, SWT.NONE);
		jarsComposite.setLayout(new GridLayout(4, false));
		GridData gd_jarsComposite = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
		gd_jarsComposite.widthHint = 580;
		gd_jarsComposite.heightHint = 123;
		jarsComposite.setLayoutData(gd_jarsComposite);
		new Label(jarsComposite, SWT.NONE);

		Label jarLabel = new Label(jarsComposite, SWT.NONE);
		jarLabel.setText("JDBC Jar: ");
		
		jarField = new Text(jarsComposite, SWT.BORDER);
		GridData gd_jarField = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_jarField.widthHint = 418;
		jarField.setLayoutData(gd_jarField);
		jarField.setEditable(false);
		
		addJarsButton = new Button(jarsComposite, SWT.NONE);
		addJarsButton.setText("Browse...");
		new Label(jarsComposite, SWT.NONE);
		
		
		Label driverClassnameLabel = new Label(jarsComposite, SWT.NONE);
		driverClassnameLabel.setText("Driver classname:");
		
		driverClassNameCombo = new Combo(jarsComposite, SWT.NONE);
		GridData gd_driverClassNameCombo = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
		gd_driverClassNameCombo.widthHint = 418;
		driverClassNameCombo.setLayoutData(gd_driverClassNameCombo);
		new Label(jarsComposite, SWT.NONE);
		
		testDriverButton = new Button(jarsComposite, SWT.NONE);
		testDriverButton.setText("Test Driver");
		testDriverButton.setEnabled(false);
		new Label(jarsComposite, SWT.NONE);
		new Label(jarsComposite, SWT.NONE);
		
		Label secondSeparator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData gd_secondSeparator = new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1);
		gd_secondSeparator.widthHint = 600;
		secondSeparator.setLayoutData(gd_secondSeparator);
		new Label(container, SWT.NONE);
		
		savePasswordCheckButton = new Button(container, SWT.CHECK);
		savePasswordCheckButton.setText("Save password");
		new Label(container, SWT.NONE);
		
		Composite savePasswordComposite = new Composite(container, SWT.NONE);
		savePasswordComposite.setLayout(new GridLayout(2, false));
		GridData gd_savePasswordComposite = new GridData(SWT.LEFT, SWT.FILL, false, false, 3, 1);
		gd_savePasswordComposite.widthHint = 590;
		gd_savePasswordComposite.heightHint = 66;
		savePasswordComposite.setLayoutData(gd_savePasswordComposite);
		new Label(savePasswordComposite, SWT.NONE);
		
		Label savePasswordLabel = new Label(savePasswordComposite, SWT.WRAP | SWT.HORIZONTAL | SWT.SHADOW_NONE);
		GridData gd_savePasswordLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_savePasswordLabel.widthHint = 538;
		savePasswordLabel.setLayoutData(gd_savePasswordLabel);
		savePasswordLabel.setText("Save password are stored on your computer in a file that's difficult, but not impossible, for an intruder to read.");

	}
}
